package id.co.rho.scoring.cid.client.mvc.scoringmodel;

import id.co.rho.scoring.cid.client.command.CommandDispatcherAsync;
import id.co.rho.scoring.cid.client.command.impl.ScoringModelCommand;
import id.co.rho.scoring.cid.client.command.impl.ScoringModelCommand.CommandType;
import id.co.rho.scoring.cid.client.command.impl.ScoringModelResult;
import id.co.rho.scoring.cid.client.model.CriteriaTree;
import id.co.rho.scoring.cid.client.mvc.AppEvents;
import id.co.rho.scoring.cid.client.security.Credential;

import java.util.ArrayList;
import java.util.List;

import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.mvc.AppEvent;
import com.extjs.gxt.ui.client.mvc.Controller;
import com.extjs.gxt.ui.client.mvc.Dispatcher;
import com.extjs.gxt.ui.client.mvc.View;
import com.extjs.gxt.ui.client.widget.Info;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.inject.Inject;

public class ScoringModelView extends View {
	private Credential credential;
	private CommandDispatcherAsync dispatcher;
	private ScoringModelUI ui;
	private Long modelId;

	@Inject
	public ScoringModelView(CommandDispatcherAsync dispacther,
			Credential credential, ScoringModelUI ui) {
		super(null);
		this.dispatcher = dispacther;
		this.credential = credential;
		this.ui = ui;
		controller = new ViewController();
	}

	@Override
	public void initialize() {
		super.initialize();
		ui.initialize();
		ui.getTree().expandAll();
		ui.getBtnAddMain().addSelectionListener(
				new SelectionListener<ButtonEvent>() {

					@Override
					public void componentSelected(ButtonEvent ce) {
						AppEvent appEvent = new AppEvent(
								AppEvents.ScoringModelEdit);
						appEvent.setData("parent", 0);
						appEvent.setHistoryEvent(true);
						appEvent.setData("modelId", modelId);
						Dispatcher.forwardEvent(appEvent);

					}
				});

		ui.getBtnAdd().addSelectionListener(
				new SelectionListener<ButtonEvent>() {
					@Override
					public void componentSelected(ButtonEvent ce) {
						AppEvent appEvent = new AppEvent(
								AppEvents.ScoringModelEdit);
						appEvent.setHistoryEvent(true);
						appEvent.setData("parent", ui.getTree()
								.getSelectionModel().getSelectedItem()
								.get("id"));
						appEvent.setData("modelId", modelId);
						Dispatcher.forwardEvent(appEvent);
					}
				});

		ui.getBtnCancel().addSelectionListener(
				new SelectionListener<ButtonEvent>() {

					@Override
					public void componentSelected(ButtonEvent ce) {
						AppEvent appEvent = new AppEvent(AppEvents.ScoringModel);
						appEvent.setData("modelId", modelId);
						Dispatcher.forwardEvent(appEvent);

					}
				});

		ui.getBtnDelete().addSelectionListener(
				new SelectionListener<ButtonEvent>() {

					@Override
					public void componentSelected(ButtonEvent ce) {
						Boolean res =deleteModel();

					}
				});

		
		ui.getBtnSave().addSelectionListener(
				new SelectionListener<ButtonEvent>() {

					@Override
					public void componentSelected(ButtonEvent ce) {
						List<CriteriaTree> treeList = new ArrayList<CriteriaTree>();
						List<ModelData> md = ui.getTree().getTreeStore()
								.getAllItems();
						String changeState="";
						if(ui.getTree().getTreeStore().isMonitorChanges()){
							for (int i = 0; i < md.size(); i++) {
								changeState="";
								changeState = (md.get(i).get("changeState") != null) ? md.get(i).get("changeState").toString(): "";
								if(!changeState.equalsIgnoreCase("delete")){
									if (md.get(i).get("parentId") == null) {
										CriteriaTree ct = new CriteriaTree();
										ct.setCriteriaName((md.get(i).get(
												"criteriaName") != null) ? md.get(i)
												.get("criteriaName").toString() : null);
										ct.setCriteriaNumber((md.get(i).get(
												"criteriaNumber") != null) ? md.get(i)
												.get("criteriaNumber").toString()
												: null);
										ct.setCriteriaRank((md.get(i).get(
												"criteriaRank") != null) ? Double
												.valueOf(md.get(i).get("criteriaRank")
														.toString()) : null);
										ct.setCriteriaWeight((md.get(i).get(
												"criteriaWeight") != null) ? Double
												.valueOf(md.get(i)
														.get("criteriaWeight")
														.toString()) : null);
										ct.setCriteriaType((md.get(i).get(
												"criteriaType") != null) ? md.get(i)
												.get("criteriaType").toString() : null);
										ct.setPosition((md.get(i).get("position") != null) ? Integer
												.valueOf(md.get(i).get("position")
														.toString()) : null);
										List<CriteriaTree> ch = getChild(md.get(i), ct);
										ct.setChild(ch);
										treeList.add(ct);
									}
									
								}
							}
							

							ScoringModelCommand cmd = new ScoringModelCommand();
							cmd.setTreeList(treeList);
							cmd.setModelId(modelId);
							cmd.setCommandType(CommandType.SAVE_ALL);
							dispatcher.execute(cmd,
									new AsyncCallback<ScoringModelResult>() {

										@Override
										public void onFailure(Throwable arg0) {
										}

										@Override
										public void onSuccess(
												ScoringModelResult arg0) {
											Info.display("Saved",
													"Data has been saved");
											AppEvent appEvent = new AppEvent(
													AppEvents.ScoringModel);
											appEvent.setData("modelId",
													arg0.getModelId());
											Dispatcher.forwardEvent(appEvent);

										}
									});							
						}else{
							Info.display("No Changes",
									"Data have no changes");
						}
						
					}
				});

		ui.getBtnEdit().addSelectionListener(
				new SelectionListener<ButtonEvent>() {

					@Override
					public void componentSelected(ButtonEvent ce) {
						AppEvent appEvent = new AppEvent(
								AppEvents.ScoringModelEdit);
						appEvent.setHistoryEvent(true);
						appEvent.setData("id", ui.getTree().getSelectionModel()
								.getSelectedItem().get("id"));
						appEvent.setData("name",
								ui.getTree().getSelectionModel()
										.getSelectedItem().get("criteriaName"));
						appEvent.setData("number",
								ui.getTree().getSelectionModel()
										.getSelectedItem()
										.get("criteriaNumber"));
						appEvent.setData("rank",
								ui.getTree().getSelectionModel()
										.getSelectedItem().get("criteriaRank"));
						appEvent.setData("weight",
								ui.getTree().getSelectionModel()
										.getSelectedItem()
										.get("criteriaWeight"));
						appEvent.setData("type",
								ui.getTree().getSelectionModel()
										.getSelectedItem().get("criteriaType"));
						appEvent.setData("parent",
								ui.getTree().getSelectionModel()
										.getSelectedItem().get("parentId"));
						appEvent.setData("modelId", modelId);
						Dispatcher.forwardEvent(appEvent);

					}
				});

	}

	private List<CriteriaTree> getChild(ModelData parent, CriteriaTree parent2) {
		List<CriteriaTree> res = new ArrayList<CriteriaTree>();
		List<ModelData> md = ui.getTree().getTreeStore().getChildren(parent);
		String changeState = "";
		if (md.size() > 0) {
			
			for (int i = 0; i < md.size(); i++) {
				changeState="";
				changeState = (md.get(i).get("changeState") != null) ? md.get(i).get("changeState").toString(): "";
				if(!changeState.equalsIgnoreCase("delete")){
					CriteriaTree ct = new CriteriaTree();
					ct.setParent(parent2);
					ct.setCriteriaName((md.get(i).get("criteriaName") != null) ? md
							.get(i).get("criteriaName").toString() : null);
					ct.setCriteriaNumber((md.get(i).get("criteriaNumber") != null) ? md
							.get(i).get("criteriaNumber").toString()
							: null);
					ct.setCriteriaRank((md.get(i).get("criteriaRank") != null) ? Double
							.valueOf(md.get(i).get("criteriaRank").toString())
							: null);
					ct.setCriteriaWeight((md.get(i).get("criteriaWeight") != null) ? Double
							.valueOf(md.get(i).get("criteriaWeight").toString())
							: null);
					ct.setCriteriaType((md.get(i).get("criteriaType") != null) ? md
							.get(i).get("criteriaType").toString() : null);
					ct.setPosition((md.get(i).get("position") != null) ? Integer
							.valueOf(md.get(i).get("position").toString()) : null);
					ct.setChild(getChild(md.get(i), ct));
					res.add(ct);
				}
			}
		}
		return res;
	}
	
	private Boolean deleteModel(){
		final Boolean res = false;
		ScoringModelCommand cmd = new ScoringModelCommand();
		cmd.setModelId(this.modelId);
		cmd.setCommandType(CommandType.DELETE);
		dispatcher.execute(cmd, new AsyncCallback<ScoringModelResult>() {

			@Override
			public void onFailure(Throwable arg0) {
			}

			@Override
			public void onSuccess(ScoringModelResult arg0) {
				AppEvent appEvent = new AppEvent(AppEvents.SearchModelEvent);
				Dispatcher.forwardEvent(appEvent);
			}
		});
		return res;
	}

	@Override
	protected void handleEvent(AppEvent event) {
		if (event.getType().equals(AppEvents.ScoringModel)) {
			ui.show();
			this.modelId = Long.valueOf(event.getData("modelId").toString());
			ui.setModelId(this.modelId);
			ScoringModelCommand cmd = new ScoringModelCommand();
			cmd.setModelId(this.modelId);
			dispatcher.execute(cmd, new AsyncCallback<ScoringModelResult>() {

				@Override
				public void onFailure(Throwable arg0) {

				}

				@Override
				public void onSuccess(ScoringModelResult arg0) {
					ui.setModel(arg0.folder);
				}
			});
		}
	}

	private class ViewController extends Controller {
		private ViewController() {
			registerEventTypes(AppEvents.ScoringModel);
		}

		@Override
		public void handleEvent(AppEvent event) {
			forwardToView(ScoringModelView.this, event);
		}
	}

}
